/*jslint vars: true, forin: true, sloppy: true */
/*global angular, ocDialog, DialogManager, DialogFactory */
ocDialog.directive("ocList", function ($compile) {
	var forEach = angular.forEach,
		isDefinded = angular.isDefined,
		minWidth = 10,
		$ = angular.element;

	function getListTemplate() {
		return $('<div class="oc-list">' +
			'<header class="oc-list-header" style="left:0"></header>' +
			'<section class="oc-list-inner"><table><thead><tr></tr></thead>' +
			'<tbody></tbody></table></section></div>');
	}

	return {
		restrict: 'E',
		compile: function (element, attrs) {
			var $list, $hC, $tC, $dC, $sC,
				header = [],
				$col = $(element[0].querySelectorAll('oc-row > oc-col')),
				$row = $(element[0].querySelector('oc-row')).empty();

			if (!$row || !$col.length) {
				throw new Error('[ocDialog > oclist]: Invalid oc-list config.');
			}

			$list = getListTemplate().prop(attrs);

			// parse attrs in <oc-row>, then clean <oc-row>.
			$row = $($row[0].outerHTML.replace('<oc-row', '<tr').replace('/oc-row>', '/tr>'));

			// parse attrs & template in <oc-col> to header[].
			forEach($col, function (c) {
				var $c = $(c),
					width = $c.attr('width'),
					label = $c.attr('label'),
					locked = $c.attr('locked');

				$c.removeAttr('width').removeAttr('label').removeAttr('locked');

				$c = $(c.outerHTML
					   .replace('<oc-col', '<td><div')
					   .replace('/oc-col>', '/div></td>'));

				$row.append($c);
				header.push({
					width: width ? Number(width) : 60,
					label: isDefinded(label) ? label : 'no title',
					locked: isDefinded(locked)
				});
			});

			// build HTML header element according with header[].
			$dC = $($list[0].querySelector('tbody'));
			$tC = $($list[0].querySelector('thead tr'));
			$hC = $($list[0].querySelector('header'));
			forEach(header, function (hC) {
				var $h, $hH = $('<label title="' + hC.label + '" style="width:' +
						hC.width + 'px">' + hC.label + '<hr/></label>'),
					$tH = $('<th><div style="width:' + hC.width + 'px"></div></th>');

				$tC.append($tH);
				$hC.append($hH);

				if (hC.locked) {
					return;
				}

				$h = $hH.find('hr').on('mousedown', function (event) {
					var initLeft = event.clientX,
						initWidth = Number($hH.css('width').match(/(\d+)px/)[1]),
						$thDiv = $tH.find('div');

					$list.on('mousemove', function (event) {
						var w = Math.max(initWidth + event.clientX - initLeft, minWidth);
						$hH.css('width', w + 'px');
						$thDiv.css('width', w + 'px');
					}).on('mouseup', function () {
						$list.off('mousemove').off('mouseup');
					});
				});
			});

			// build data area.
			$dC.append($row);

			// bind oc-link-inner scroll listener.
			$sC = $list.find('section').on('scroll', function () {
				$hC[0].style.left = '-' + $sC[0].scrollLeft + 'px';
			});

			// Linking
			return {
				post: function (scope, element) {
					element.replaceWith($compile($list)(scope));
				}
			};
		}
	};
});
